package com.team.cloudsharing.service.file;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.amazonaws.AmazonClientException;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.CannedAccessControlList;
import com.amazonaws.services.s3.model.CopyObjectRequest;
import com.amazonaws.services.s3.model.DeleteObjectRequest;
import com.amazonaws.services.s3.model.PutObjectRequest;
import com.team.cloudsharing.dao.actionlog.ActionLogDAO;
import com.team.cloudsharing.dao.actionlog.ActionLogDO;
import com.team.cloudsharing.dao.file.FileDAO;
import com.team.cloudsharing.dao.file.FileDO;
import com.team.cloudsharing.dao.folder.FolderDAO;
import com.team.cloudsharing.dao.folder.FolderDO;
import com.team.cloudsharing.dao.sharefolder.ShareFolderDAO;
import com.team.cloudsharing.dao.user.UserDAO;
import com.team.cloudsharing.dao.user.UserDO;
import com.team.cloudsharing.dto.File;
import com.team.cloudsharing.dto.PathDTO;
import com.team.cloudsharing.dto.TextFile;
import com.team.cloudsharing.service.folder.FolderService;
import com.team.cloudsharing.service.sharefolder.ShareFolderService;
import com.team.cloudsharing.service.user.UserService;
import com.team.cloudsharing.ultis.Constant;
import com.team.cloudsharing.ultis.IDGenerator;
import com.team.cloudsharing.ultis.S3Util;

@Service("fileService")
public class FileServiceImpl implements FileService {

	final static Logger logger = Logger.getLogger(FileServiceImpl.class);

	@Autowired
	FolderService folderService;
	
	@Autowired
	ShareFolderService shareFolderService;

	@Autowired
	FolderDAO folderDAO;

	@Autowired
	FileDAO fileDAO;
	
	@Autowired
	ActionLogDAO actionLogDAO;

	@Autowired
	UserDAO userDAO;
	
	@Autowired
	ShareFolderDAO shareFolderDAO;
	
	@Autowired
	UserService userService;
	
	@Value("${AMAZON_ACCESS_KEY}")
	String amazonAccessKey;

	@Value("${AMAZON_SECRET_KEY}")
	String amazonSecretKey;

	@Value("${AMAZON_BUCKET}")
	String amazonBucket;
	
	@Override
	public String saveFileUploaded(File file) {
		String statusSaveFileUpload = Constant.SAVE_FILE_FAILURE;
		UserDO userDO = userDAO.findUserByUserEmail(file.getUserEmail());
		if (userDO != null){
			FolderDO folderDO = getFolderDOStorageFile(file.getFilePath(), userDO);
			FileDO fileDOCheck = fileDAO.findFileByFileNameInFolder(file.getFileName(), folderDO);
			if (fileDOCheck != null){
				userService.decreaseUsedCapacity(file.getUserEmail(), fileDOCheck.getFileCapacity());
				fileDOCheck.setFileName(file.getFileName());
				fileDOCheck.setModifiedUserId(userDO.getUserId());
				fileDOCheck.setFileCapacity(file.getFileCapacity());
				fileDOCheck.setFileInTrash(false);
				long fileId = fileDAO.updateFile(fileDOCheck);
				userService.increaseUsedCapacity(file.getUserEmail(), file.getFileCapacity());
				if (fileId > 0){
					List<ActionLogDO> actionLogDOs = actionLogDAO.setAllStatusByUserDO(userDO);
					if (actionLogDOs !=null){
					 for (ActionLogDO actionLogDO : actionLogDOs) {
							actionLogDO.setStatus(true);
							actionLogDAO.insertActionLog(actionLogDO);
						}
					}
					if (file.getMacAddress()!=null && !file.getMacAddress().isEmpty()){
						actionLogDAO.setStatusByMacAddress(file.getMacAddress());
					}
					shareFolderService.sendNotificationSynchoronize(file.getUserEmail());
					statusSaveFileUpload = Constant.UPDATE_FILE_SUCCESS;
				}
			}
			else{
				FileDO fileDO = new FileDO();
				if (file.getFileId() != null && file.getFileId() > 0 ){
					fileDO.setFileId(file.getFileId());
				}
				fileDO.setFileName(file.getFileName());
				fileDO.setFilePath(file.getFilePath());
				fileDO.setFileUrl(getRandomFileUrl());
				fileDO.setModifiedUserId(userDO.getUserId());
				fileDO.setFileCapacity(file.getFileCapacity());
				fileDO.setFileInTrash(false);
				fileDO.setFilePermission(file.getFilePermission());
				fileDO.setFolderDO(folderDO);
				long fileId = fileDAO.insertFile(fileDO);
				userService.increaseUsedCapacity(file.getUserEmail(), file.getFileCapacity());
				if (fileId > 0){
					List<ActionLogDO> actionLogDOs = actionLogDAO.setAllStatusByUserDO(userDO);
					if (actionLogDOs != null) {
					 for (ActionLogDO actionLogDO : actionLogDOs) {
							actionLogDO.setStatus(true);
							actionLogDAO.insertActionLog(actionLogDO);
						}
					}
					if (file.getMacAddress()!=null && !file.getMacAddress().isEmpty()){
						actionLogDAO.setStatusByMacAddress(file.getMacAddress());
					}
					shareFolderService.sendNotificationSynchoronize(file.getUserEmail());
					statusSaveFileUpload = Constant.SAVE_FILE_SUCCESS;
				}
			}
		}
		return statusSaveFileUpload;
	}
	
	private FolderDO getFolderDOStorageFile(String filePath, UserDO userDO){
		FolderDO folderDO = null;
		if (filePath == null || filePath.isEmpty()){
			folderDO = folderDAO.findROOTFolderOfUser(userDO);
		}
		else{
			String[] folderNameAndFolderPath = splitFolderNameAndFolderPathInFilePath(filePath);
			folderDO = folderDAO.findFolderByFolderNameAndFolderPathAndUserId(folderNameAndFolderPath[0], folderNameAndFolderPath[1], userDO);
			if (folderDO == null){
				folderDO = folderService.getRealFolderDOFromShareFolder(filePath, userDO.getUserEmail());
			}
		}
		return folderDO;
	}
	
	@Override
	public String[] splitFolderNameAndFolderPathInFilePath(String filePath){
		String[] folderNameAndFolderPath = new String[2];
		String[] filePathSplit = filePath.split(Constant.SUFFIX);
		if (filePathSplit.length == 1){
			folderNameAndFolderPath[0] = filePathSplit[0];
			folderNameAndFolderPath[1] = Constant.EMPTY_PATH;
		}
		else{
			folderNameAndFolderPath[0] = filePathSplit[filePathSplit.length - 1];
			folderNameAndFolderPath[1] = Constant.EMPTY_PATH;
			for(int i=0; i < filePathSplit.length - 1; i++)
				folderNameAndFolderPath[1] += filePathSplit[i] + Constant.SUFFIX;
			folderNameAndFolderPath[1] = removeCharactersSUFFIXInTheEnd(folderNameAndFolderPath[1]);
		}
		return folderNameAndFolderPath;
	}
	
	private String removeCharactersSUFFIXInTheEnd(String stringInput){
		if (! stringInput.isEmpty() && stringInput.charAt(stringInput.length() - 1) == '/'){
			stringInput = stringInput.substring(0, stringInput.length() - 1);
		}
		return stringInput;
	}
	
	private String getRandomFileUrl(){
		String fileUrlRandom = null;
		do{
			fileUrlRandom = IDGenerator.randomString(10);
		}
		while(fileDAO.findFileByFileUrl(fileUrlRandom) != null);
		return fileUrlRandom;
	}
	
	@Override
	public File downloadFile(String fileUrl) {
		File fileDownload = new File();
		FileDO fileDO = fileDAO.findFileByFileUrl(fileUrl);
		if (fileDO != null){
			if (fileDO.getFilePermission() == Constant.DOCUMENT_PUBLIC){
				FolderDO folderDO = folderDAO.findFolderById(fileDO.getFolderDO().getFolderId());
				fileDownload.setUserEmail(folderDO.getUserDO().getUserEmail());
				fileDownload.setFileName(fileDO.getFileName());
				fileDownload.setFilePath(fileDO.getFilePath());
				fileDownload.setFileCapacity(fileDO.getFileCapacity());
			}
		}
		return fileDownload;
	}

	@Override
	public String moveFileToTrash(File file) {
		String statusMoveToTrash = Constant.MOVE_FILE_TO_TRASH_FAILURE;
		UserDO userDO = userDAO.findUserByUserEmail(file.getUserEmail());
		FolderDO folderDO = getFolderDOStorageFile(file.getFilePath(), userDO);
		if (folderDO != null){
			FileDO fileDO = fileDAO.findFileByFileNameInFolder(file.getFileName(), folderDO);
			fileDO.setFileInTrash(true);
			Long fileIdUpdated = fileDAO.updateFile(fileDO);
			if (fileIdUpdated > 0){
				statusMoveToTrash = Constant.MOVE_FILE_TO_TRASH_SUCCESS;
				shareFolderService.sendNotificationSynchoronize(file.getUserEmail());
				List<ActionLogDO> actionLogDOs = actionLogDAO.setAllStatusByUserDO(userDO);
				if (actionLogDOs != null) {
				 for (ActionLogDO actionLogDO : actionLogDOs) {
						actionLogDO.setStatus(true);
						actionLogDAO.insertActionLog(actionLogDO);
					}
				}
				if (file.getMacAddress()!=null && !file.getMacAddress().isEmpty()){
					actionLogDAO.setStatusByMacAddress(file.getMacAddress());
				}
			}
		}
		return statusMoveToTrash;
	}

	@Override
	public String restoreFileFromTrash(File file) {
		String statusRestore = Constant.RESTORE_FILE_FROM_TRASH_FAILURE;
		UserDO userDO = userDAO.findUserByUserEmail(file.getUserEmail());
		FolderDO folderDO = getFolderDOStorageFile(file.getFilePath(), userDO);
		if (folderDO != null){
			if (! folderDO.isFolderInTrash()){
				FileDO fileDO = fileDAO.findFileByFileNameInFolder(file.getFileName(), folderDO);
				fileDO.setFileInTrash(false);
				Long fileIdUpdated = fileDAO.updateFile(fileDO);
				if (fileIdUpdated > 0){
					statusRestore = Constant.RESTORE_FILE_FROM_TRASH_SUCCESS;
					shareFolderService.sendNotificationSynchoronize(file.getUserEmail());
					List<ActionLogDO> actionLogDOs = actionLogDAO.setAllStatusByUserDO(userDO);
					if (actionLogDOs != null) {
					 for (ActionLogDO actionLogDO : actionLogDOs) {
							actionLogDO.setStatus(true);
							actionLogDAO.insertActionLog(actionLogDO);
						}}
					if (file.getMacAddress()!=null && !file.getMacAddress().isEmpty()){
						actionLogDAO.setStatusByMacAddress(file.getMacAddress());
					}
				}
			}
			else{
				statusRestore = Constant.RESTORE_FILE_FAILURE_BECAUSE_FOLDER_PARENT;
			}
		}
		return statusRestore;
	}

	@Override
	public String deleteFile(File file) {
//		String filePath = file.getFilePath();
//		String fileName = file.getFileName();
//		String userEmail = file.getUserEmail();
//		System.out.println(filePath + " - " + fileName + " - " + userEmail);
		
		UserDO userDO = userDAO.findUserByUserEmail(file.getUserEmail());
		FolderDO folderDO = getFolderDOStorageFile(file.getFilePath(), userDO);
		if (folderDO != null){
			FileDO fileDO = fileDAO.findFileByFileNameInFolder(file.getFileName(), folderDO);
			Boolean deleteFileStatus = fileDAO.deleteFile(fileDO.getFileId());
			deleteS3File(file);
			if (deleteFileStatus) {
				List<ActionLogDO> actionLogDOs = actionLogDAO.setAllStatusByUserDO(userDO);
				if (actionLogDOs != null) {
				 for (ActionLogDO actionLogDO : actionLogDOs) {
						actionLogDO.setStatus(true);
						actionLogDAO.insertActionLog(actionLogDO);
					}
				}
				if (file.getMacAddress()!=null && !file.getMacAddress().isEmpty()){
					actionLogDAO.setStatusByMacAddress(file.getMacAddress());
				}
				shareFolderService.sendNotificationSynchoronize(file.getUserEmail());
				userService.decreaseUsedCapacity(file.getUserEmail(), fileDO.getFileCapacity());
				return Constant.DELETE_FILE_SUCCESS;
			}
		}
		return Constant.DELETE_FILE_FAILURE;
	}
	
	private void deleteS3File(File file){
		AWSCredentials myCredentials = new BasicAWSCredentials(amazonAccessKey,	amazonSecretKey);
		AmazonS3 client = new AmazonS3Client(myCredentials);
		if (file.getFilePath().isEmpty()) {
			client.deleteObject(new DeleteObjectRequest(amazonBucket, file.getUserEmail() + Constant.SUFFIX + file.getFileName()));
		} else {
			client.deleteObject(new DeleteObjectRequest(amazonBucket, file.getUserEmail() + Constant.SUFFIX + file.getFilePath() + Constant.SUFFIX + file.getFileName()));
		}
	}

	@Override
	public String renameFile(PathDTO pathDTO) {
		String folderPath;
		String folderName;
		if (pathDTO.getNewDocumentPath().isEmpty()) {
			folderPath = "";
			folderName = pathDTO.getUserEmail();
		} else {
			if (!pathDTO.getNewDocumentPath().contains(Constant.SUFFIX)) {
				folderPath = "";
				folderName = pathDTO.getNewDocumentPath();
			} else {
				folderPath = StringUtils.substringBeforeLast(pathDTO.getNewDocumentPath(), Constant.SUFFIX);
				folderName = StringUtils.substringAfterLast(pathDTO.getNewDocumentPath(), Constant.SUFFIX);
			}
		}
		UserDO userDO = userDAO.findUserByUserEmail(pathDTO.getUserEmail());
		FolderDO folderDO = folderDAO.findFolderByFolderNameAndFolderPathAndUserId(folderName, folderPath, userDO);
		if (isFileExistInFolder(pathDTO.getNewDocumentName(), folderDO) == null) {
			String oldFullPath = S3Util.convertDocumentPathAndNameToFullPathForS3(pathDTO.getUserEmail(), pathDTO.getOldDocumentPath(), pathDTO.getOldDocumentName(), pathDTO.getDocumentType());
			String newFullPath = S3Util.convertDocumentPathAndNameToFullPathForS3(pathDTO.getUserEmail(), pathDTO.getNewDocumentPath(), pathDTO.getNewDocumentName(), pathDTO.getDocumentType());
			if (moveFileS3(oldFullPath, newFullPath) == Constant.MOVE_FILE_SUCCESS) {
				FileDO fileDO = fileDAO.findFileById(pathDTO.getDocumentId());
				
				fileDO.setFileName(pathDTO.getNewDocumentName());
				fileDO.setModifiedDate(new Date());
				long fileId = fileDAO.updateFile(fileDO);
				if (fileId > 0) {
					 List<ActionLogDO> actionLogDOs = actionLogDAO.setAllStatusByUserDO(userDO);
					 if (actionLogDOs != null) {
					 for (ActionLogDO actionLogDO : actionLogDOs) {
							actionLogDO.setStatus(true);
							actionLogDAO.insertActionLog(actionLogDO);
						}
					 }
					if (pathDTO.getMacAddress()!=null && !pathDTO.getMacAddress().isEmpty()){
						System.out.println("Move to here! Wrong!");
						actionLogDAO.setStatusByMacAddress(pathDTO.getMacAddress());
					}
					shareFolderService.sendNotificationSynchoronize(pathDTO.getUserEmail());
					return Constant.RENAME_FILE_SUCCESS;
				}
			}
		}
		return Constant.RENAME_FILE_FAILURE;
	}
	
	private FileDO isFileExistInFolder(String fileName, FolderDO folderDO) {
	List<FileDO> listFileDO = new ArrayList<FileDO>(folderDO.getFileDO());
	if (listFileDO != null) {
		for (int i = 0; i < listFileDO.size(); i++) {
			if (fileName.equals(listFileDO.get(i).getFileName())) {
				return listFileDO.get(i);
			}
		}
	}
	return null;
}
	@Override
	public String moveFileToAnotherFolder(PathDTO pathDTO) {
		String newFolderPath;
		String newFolderName;
		String oldFullPath;
		String newFullPath;
		String newFileNameIfExist = "";
		if (pathDTO.getNewDocumentPath().isEmpty()) {
			newFolderPath = "";
			newFolderName = pathDTO.getUserEmail();
		} else {
			if (!pathDTO.getNewDocumentPath().contains(Constant.SUFFIX)) {
				newFolderPath = "";
				newFolderName = pathDTO.getNewDocumentPath();
			} else {
				newFolderPath = StringUtils.substringBeforeLast(pathDTO.getNewDocumentPath(), Constant.SUFFIX);
				newFolderName = StringUtils.substringAfterLast(pathDTO.getNewDocumentPath(), Constant.SUFFIX);
			}
		}
		UserDO userDO = userDAO.findUserByUserEmail(pathDTO.getUserEmail());
		FolderDO folderDO = folderDAO.findFolderByFolderNameAndFolderPathAndUserId(newFolderName, newFolderPath, userDO);
		oldFullPath = S3Util.convertDocumentPathAndNameToFullPathForS3(pathDTO.getUserEmail(), pathDTO.getOldDocumentPath(), pathDTO.getOldDocumentName(), pathDTO.getDocumentType());
		if (isFileExistInFolder(pathDTO.getNewDocumentName(), folderDO) == null) {
			newFullPath = S3Util.convertDocumentPathAndNameToFullPathForS3(pathDTO.getUserEmail(), pathDTO.getNewDocumentPath(), pathDTO.getNewDocumentName(), pathDTO.getDocumentType());
		} else {
			newFileNameIfExist = makeNewFileNameIfExist(pathDTO, folderDO);
			newFullPath = S3Util.convertDocumentPathAndNameToFullPathForS3(pathDTO.getUserEmail(), pathDTO.getNewDocumentPath(), newFileNameIfExist, pathDTO.getDocumentType());
		}
		if (moveFileS3(oldFullPath, newFullPath) == Constant.MOVE_FILE_SUCCESS) {
			FileDO fileDO = fileDAO.findFileById(pathDTO.getDocumentId());
			fileDO.setModifiedDate(new Date());
			fileDO.setFilePath(pathDTO.getNewDocumentPath());
			if (!newFileNameIfExist.isEmpty()) {
				fileDO.setFileName(newFileNameIfExist);
			}
			fileDO.setFolderDO(folderDO);
			long fileId = fileDAO.updateFile(fileDO);
			if (fileId > 0) {
				List<ActionLogDO> actionLogDOs = actionLogDAO.setAllStatusByUserDO(userDO);
				if (actionLogDOs != null) {
				 for (ActionLogDO actionLogDO : actionLogDOs) {
						actionLogDO.setStatus(true);
						actionLogDAO.insertActionLog(actionLogDO);
					}
				}
				if (pathDTO.getMacAddress()!=null && !pathDTO.getMacAddress().isEmpty()){
					actionLogDAO.setStatusByMacAddress(pathDTO.getMacAddress());
				}
				shareFolderService.sendNotificationSynchoronize(pathDTO.getUserEmail());
				return Constant.MOVE_FILE_TO_ANOTHER_FOLDER_SUCCESS;
			}
		}
		return Constant.MOVE_FILE_TO_ANOTHER_FOLDER_FAILURE;
	}
	
	@Override
	public String copyFileToAnotherFolder(PathDTO pathDTO) {
		String newFolderPath;
		String newFolderName;
		String oldFullPath;
		String newFullPath;
		String newFileNameIfExist = "";
		if (pathDTO.getNewDocumentPath().isEmpty()) {
			newFolderPath = "";
			newFolderName = pathDTO.getUserEmail();
		} else {
			if (!pathDTO.getNewDocumentPath().contains(Constant.SUFFIX)) {
				newFolderPath = "";
				newFolderName = pathDTO.getNewDocumentPath();
			} else {
				newFolderPath = StringUtils.substringBeforeLast(pathDTO.getNewDocumentPath(), Constant.SUFFIX);
				newFolderName = StringUtils.substringAfterLast(pathDTO.getNewDocumentPath(), Constant.SUFFIX);
			}
		}
		UserDO userDO = userDAO.findUserByUserEmail(pathDTO.getUserEmail());
		FolderDO folderDO = folderDAO.findFolderByFolderNameAndFolderPathAndUserId(newFolderName, newFolderPath, userDO);
		oldFullPath = S3Util.convertDocumentPathAndNameToFullPathForS3(pathDTO.getUserEmail(), pathDTO.getOldDocumentPath(), pathDTO.getOldDocumentName(), pathDTO.getDocumentType());
		if (isFileExistInFolder(pathDTO.getNewDocumentName(), folderDO) == null) {
			newFullPath = S3Util.convertDocumentPathAndNameToFullPathForS3(pathDTO.getUserEmail(), pathDTO.getNewDocumentPath(), pathDTO.getNewDocumentName(), pathDTO.getDocumentType());
		} else {
			newFileNameIfExist = makeNewFileNameIfExist(pathDTO, folderDO);
			newFullPath = S3Util.convertDocumentPathAndNameToFullPathForS3(pathDTO.getUserEmail(), pathDTO.getNewDocumentPath(), newFileNameIfExist, pathDTO.getDocumentType());
		}
		if (copyFileS3(oldFullPath, newFullPath)) {
			FileDO fileDOOld = fileDAO.findFileById(pathDTO.getDocumentId());
			FileDO fileDO = new FileDO();
			fileDO.setDateCreate(new Date());
			fileDO.setFileCapacity(fileDOOld.getFileCapacity());
			fileDO.setFileName(fileDOOld.getFileName());
			if (!newFileNameIfExist.isEmpty()) {
				fileDO.setFileName(newFileNameIfExist);
			}
			fileDO.setFilePath(pathDTO.getNewDocumentPath());
			fileDO.setFilePermission(1);
			fileDO.setModifiedDate(new Date());
			fileDO.setFileUrl(getRandomFileUrl());
			fileDO.setFileInTrash(fileDOOld.isFileInTrash());
			fileDO.setFileBackup(fileDOOld.isFileBackup());
			fileDO.setModifiedUserId(userDO.getUserId());
			fileDO.setFolderDO(folderDO);
			long fileId = fileDAO.insertFile(fileDO);
			if (fileId > 0) {
				List<ActionLogDO> actionLogDOs = actionLogDAO.setAllStatusByUserDO(userDO);
				if (actionLogDOs != null) {
				 for (ActionLogDO actionLogDO : actionLogDOs) {
						actionLogDO.setStatus(true);
						actionLogDAO.insertActionLog(actionLogDO);
					}}
				if (pathDTO.getMacAddress()!=null && !pathDTO.getMacAddress().isEmpty()){
					actionLogDAO.setStatusByMacAddress(pathDTO.getMacAddress());
				}
				shareFolderService.sendNotificationSynchoronize(pathDTO.getUserEmail());
				return Constant.MOVE_FILE_TO_ANOTHER_FOLDER_SUCCESS;
			}
		}
		return Constant.MOVE_FILE_TO_ANOTHER_FOLDER_FAILURE;
	}
	
	
	
	
	private String makeNewFileNameIfExist(PathDTO pathDTO, FolderDO folderDO) {
		String fileNameWithoutExtension = StringUtils.substringBeforeLast(pathDTO.getNewDocumentName(), ".");
		String extension = StringUtils.substringAfterLast(pathDTO.getNewDocumentName(), ".");
		List<FileDO> fileDOs = fileDAO.findAllFileByFileNamePatternInFolder(fileNameWithoutExtension + " (%", folderDO);
		List<Integer> fileIndexes = new ArrayList<Integer>();
		if (fileDOs == null) {
			return fileNameWithoutExtension + " (1)." + extension;
		} else {
			for (int i = 0; i < fileDOs.size(); i++) {
				String fileName = StringUtils.substringBeforeLast(fileDOs.get(i).getFileName(), ".");
				if (Character.isDigit(fileName.charAt(fileName.length() - 2))) {
					fileIndexes.add(Character.getNumericValue(fileName.charAt(fileName.length() - 2)));
				}
			}
			int finalIndex = Collections.max(fileIndexes) + 1;
			return fileNameWithoutExtension + " (" + finalIndex + ")." + extension;
		}
	}

	private String moveFileS3(String oldFullPath, String newFullPath) {
		String message = Constant.MOVE_FILE_SUCCESS;
		AWSCredentials myCredentials = new BasicAWSCredentials(amazonAccessKey,	amazonSecretKey);
		AmazonS3 client = new AmazonS3Client(myCredentials);
		try {
			if (copyFileS3(oldFullPath, newFullPath)) {
				client.deleteObject(new DeleteObjectRequest(amazonBucket, oldFullPath));
			} else {
				return Constant.MOVE_FILE_FAILURE;
			}
		} catch (AmazonServiceException ase) {
			logger.error(ase.getMessage());
			message = Constant.MOVE_FILE_FAILURE;
		} catch (AmazonClientException ace) {
			logger.error(ace.getMessage());
			message = Constant.MOVE_FILE_FAILURE;
		}
		return message;
	}
	
	private boolean copyFileS3(String oldFullPath, String newFullPath) {
		System.out.println(oldFullPath);
		System.out.println(newFullPath);
		AWSCredentials myCredentials = new BasicAWSCredentials(amazonAccessKey,	amazonSecretKey);
		AmazonS3 client = new AmazonS3Client(myCredentials);
		try {
			CopyObjectRequest copyObjectRequest = new CopyObjectRequest(amazonBucket, oldFullPath, amazonBucket, newFullPath);
			client.copyObject(copyObjectRequest);
		} catch (AmazonServiceException ase) {
			logger.error(ase.getMessage());
			return false;
		} catch (AmazonClientException ace) {
			logger.error(ace.getMessage());
			return false;
		}
		return true;
	}
	
	@Override
	public String getFileUrlByFileId(String fileId) {
		return fileDAO.findFileById(Long.valueOf(fileId)).getFileUrl();
	}

	@Override
	public String createTextFile(TextFile textFile) {
		String statusCreate = Constant.CREATE_FILE_FAILURE;
		try {
			java.io.File file = new java.io.File(textFile.getFileName());
			if (!file.exists()) {
				file.createNewFile();
			}
			FileWriter fw = new FileWriter(file.getAbsoluteFile());
			BufferedWriter bw = new BufferedWriter(fw);
			bw.write(textFile.getFileContent());
			bw.close();

			File fileUpload = new File();
			fileUpload.setFileName(textFile.getFileName());
			fileUpload.setDateCreate(new Date());
			fileUpload.setFilePath(textFile.getFilePath());
			fileUpload.setFileCapacity(file.length());
			fileUpload.setUserEmail(textFile.getUserEmail());
			fileUpload.setFilePermission(Constant.DOCUMENT_PUBLIC);
			saveFileUploaded(fileUpload);
			
			AWSCredentials myCredentials = new BasicAWSCredentials(amazonAccessKey,	amazonSecretKey);
			AmazonS3 client = new AmazonS3Client(myCredentials);
			String fileName = "";
			if (textFile.getFilePath().isEmpty()){
				fileName = textFile.getUserEmail() + Constant.SUFFIX + textFile.getFileName();
			}
			else{
				fileName = textFile.getUserEmail() + Constant.SUFFIX + textFile.getFilePath() + Constant.SUFFIX + textFile.getFileName();
			}
			file = new java.io.File(textFile.getFileName());
			client.putObject(new PutObjectRequest(amazonBucket, fileName, file).withCannedAcl(CannedAccessControlList.PublicRead));
			file.delete();
			statusCreate = Constant.CREATE_FILE_SUCCESS;
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return statusCreate;
	}
}
